<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>let, const, var三种变量声明符号的说明</title>
    <script src="../../js/jquery-3.4.1.js"></script>
</head>
<body>

</body>
<script>

    /*
    功能:
        let操作符的说明.
    说明:
        1. 声明了一个let类型的变量后, 如果为初始化, 自会自动初始化为undefined;
            - var与let相同.
        2. let操作符声明的变量不允许重复声明, 否则会抛出异常;
            - var声明的变量会互相影响: 后声明的会覆盖前面声明的.
        3. 不同作用域的同名let变量互不影响, 抗干扰能力强.
            - var声明的变量会互相影响: 后声明的会覆盖前面声明的.
            - let是块级作用域，函数内部使用let定义后，对函数外部无影响; 但是var相当于是全局的.
     */
    let str1 = "  sds  ";

    //使用反引号来声明长字符串.
    const longString = `
    <div>sdasd</div>
    <div>sdasd</div>
    <div>sdasd</div>
    <div>sdasd</div>
    `;

    $(function () {
        letDemo1();
        //letDemo2();
        letDemo3();
        letDemo4();

        //constDemo1();
        constDemo2();
        str2number("1");
    });

    /**
     * 功能:
     *      let操作符的特性1验证: 未初始化时和var操作符的意义相同.
     * 输出:
     * ```
     * let1: undefined
     * var1: undefined
     * ```
     * 说明:
     *      1. 如果未初始化, 就会自动初始化为undefined.
     */
    function letDemo1() {
        let let1;
        var var1;
        console.log("let1: " + let1);
        console.log("var1: " + var1);
    }

    /**
     * 功能:
     *      let操作符的特性2验证: 使用未声明的变量，表现不同.
     * 输出:
     *      报错: jquery-3.4.1.js:3852 Uncaught ReferenceError: var1 is not defined
     * 说明:
     *      1. var和let在谷歌浏览器中不定义就使用时会报错.
     */
    function letDemo2() {
        console.log("var2: " + var2); // 会报错: jquery-3.4.1.js:3852 Uncaught ReferenceError: var2 is not defined
        console.log("let2: " + let2); // 会报错: jquery-3.4.1.js:3852 Uncaught ReferenceError: let2 is not defined
    }

    /**
     * 功能:
     *      let操作符的特性3验证: 不允许重复定义导致的覆盖.
     * 说明:
     *      1. 如果去掉函数中的注释就会导致报错`Uncaught SyntaxError: Identifier 'let3' has already been declared`, 也就是说let操作符不允许重复定义, 但是var操作符可以.
     */
    function letDemo3() {
        var var3 = 'i`m var3-1';
        let let3 = 'i`m let3-1';

        var var3 = 'i`m var3-2'; // 这里的var3定义会覆盖掉前面的var3定义.
        //let let3 = 'i`m let3-2'; // 会报错: Uncaught SyntaxError: Identifier 'let3' has already been declared

        console.log(var3);
        console.log(let3);
    }

    /**
     * 功能:
     *      let操作符的特性4验证: 作用域不同.
     * 输出:
     * ```
     * var4: i`m var4-2
     * let4: i`m let4-1
     * ```
     * 说明:
     *      1. 可以发现, 不同作用域的var初始化会产生覆盖, 但是let可以避免这个, 原因:
     *          - let操作符不允许重复定义;
     *          - let操作符有明确的作用域概念, 彼此互不影响.
     */
    function letDemo4() {
        var var4 = 'i`m var4-1';
        let let4 = 'i`m let4-1';

        {
            var var4 = 'i`m var4-2';
            let let4 = 'i`m let4-2';
        }

        console.log("var4: " + var4);
        console.log("let4: " + let4);
    }

    /**
     * 功能:
     *      const的特性1验证: const声明的变量必须初始化.
     * 说明:
     *      1. 不初始化就会报错.
     *      2. 注意被const声明的变量如果没有初始化是不会通过浏览器检测的, 可以想象为js会被浏览器预编译一次, 如果发现const声明的变量
     *      未被初始化就会抛出异常.
     */
    function constDemo1() {
        const const1 = 1;//会报错: Uncaught SyntaxError: Missing initializer in const declaration
    }

    /**
     * 功能:
     *      const的特性2验证: const声明的变量相当于是一个常量, 类似java中的被final修饰的常量, 是不可变的常量.
     * 说明:
     *      1. 被const声明的变量不可以再次改变, 是一个常量.
     *          - 但是var和let声明的变量都可以重新改变.
     */
    function constDemo2() {
        const const2 = 'str1';
        //const2 = 'str2'; //报错: Uncaught TypeError: Assignment to constant variable. 中文: 赋值给常量变量。
        console.log(const2);
    }

</script>
</html>